/*

 */
package org.vectrics.graphics;

import java.io.InputStream;
import java.util.HashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.vectrics.SystemException;
import org.vectrics.common.util.ConfigurationReader;
import org.vectrics.config.ApplicationConfiguration;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * @author mmoore
 */
public class DynaGraphicsConfig extends ConfigurationReader {
    private HashMap imageConfigMap = new HashMap();
    private String resourcesPath = null;

    
    
    public DynaGraphicsConfig(String contents) {
        this.parse(contents);
    }
    
    public DynaGraphicsConfig(InputStream contents) {
    	this.parse(contents);
	}

	/**
     * @return Returns the resourcesPath.
     */
    public String getResourcesPath() {
        return resourcesPath;
    }
    
    /**
     * @param resourcesPath The resourcesPath to set.
     */
    public void setResourcesPath(String resourcesPath) {
        this.resourcesPath = resourcesPath;
    }
    
    public void load(Document document) {
        NodeList mainElements = document.getElementsByTagName("dyna-image-config");
        Element mainElement = (Element)mainElements.item(0);
        resourcesPath = mainElement.getAttribute("resources-path");
        if (resourcesPath == null)
        	throw new SystemException("Dynamic Graphics Configuration is missing a 'resources-path'");
        
        loadImages(mainElement);
    }
    
    private void loadImages(Element mainElement) {
        NodeList children = mainElement.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            if (child instanceof Element) {
                Element element = (Element)child;
                if (element.getTagName().equals("image")) {
                    loadImage(element);
                } else {
                    throw new SystemException("Configuration exception, 'image' tag expected, found: " + element.getTagName());
                }
            }
        }
    }
    
    /*
     * Load configuration for image.
     */
    private void loadImage(Element imageElement) {
        ImageConfiguration imageConfig = new ImageConfiguration(imageConfigMap);
        imageConfig.setName(imageElement.getAttribute("name"));

        String parentStr = imageElement.getAttribute("extends");
        if ((parentStr != null) && (parentStr.length() > 0))
            imageConfig.setParentName(parentStr);
        
        String widthStr = imageElement.getAttribute("width");
        if ((widthStr != null) && (widthStr.length() > 0))
            imageConfig.setWidth(new Integer(widthStr));
        
        String heightStr = imageElement.getAttribute("height");
        if ((heightStr != null) && (heightStr.length() > 0))
        	imageConfig.setHeight(new Integer(heightStr));
        
        String backgroundStr = imageElement.getAttribute("background");
        if ((backgroundStr != null) && (backgroundStr.trim().length() > 0)) {
            if (backgroundStr.startsWith("#")) {
                imageConfig.setBackground(backgroundStr);
            } else {
                throw new SystemException("Illegal background value " + backgroundStr + " for image: " + imageConfig.getName());
            }
        }
        
        if (imageConfig.getName() == null)
            throw new SystemException("Configuration error, image missing name");
        
        if (imageConfigMap.containsKey(imageConfig.getName())) {
            throw new SystemException("Configuration error, repeated image name: " + imageConfig.getName());
        } else {
            imageConfigMap.put(imageConfig.getName(), imageConfig);
        }
        loadLayers(imageConfig, imageElement);
    }
    
    
    private void loadLayers(ImageConfiguration imageConfig, Element imageElement) {
        NodeList layers = imageElement.getElementsByTagName("layer");
        for (int i = 0; i < layers.getLength(); i++) {
            Element layerElement = (Element)layers.item(i);
            String name = layerElement.getAttribute("name");
            LayerConfiguration layer = null;
            
            NodeList layerChildren = layerElement.getChildNodes();
            for (int j = 0; j < layerChildren.getLength(); j++) {
                Node node = layerChildren.item(j);
                if (node instanceof Element) {
                    Element layerChildElement = (Element)node;
                    if (layerChildElement.getTagName().equals("text")) {
                        String value = layerChildElement.getAttribute("value");
                        String valueCode = layerChildElement.getAttribute("value-code");
                        String valueParam = layerChildElement.getAttribute("value-param");
                        String color = layerChildElement.getAttribute("color");
                        String bold = layerChildElement.getAttribute("bold");
                        
                        String size = layerChildElement.getAttribute("size");
                        if (size != null) {
                            
                        }
                        layer = new LayerTextConfiguration();
                        LayerTextConfiguration textLayer = (LayerTextConfiguration)layer;
                        textLayer.setValue(value);
                        if ((valueCode != null) && (valueCode.length() > 0))
                            textLayer.setValueCode(valueCode);
                        else if ((valueParam != null) && (valueParam.length() > 0))
                            textLayer.setValueParam(valueParam);
                        else if ((value != null) && (value.length() > 0))
                            textLayer.setValue(value);
                        else
                            throw new SystemException("Layer text element missing 'value', 'value-param' or 'value-code' attributes: image = " + imageConfig.getName());
                        
                        textLayer.setSize(Integer.parseInt(size));
                        textLayer.setColor(color);
                        if ((bold != null) && (bold.length() > 0)) {
                            if (bold.toLowerCase().startsWith("tr"))
                                textLayer.setBold(true);
                        }
                    } else if (layerChildElement.getTagName().equals("image-file")) {
                        String path = layerChildElement.getAttribute("path");
                        if ((path == null) || (path.length() == 0)) {
                            throw new SystemException("'image-file' tag is missing 'path' attribute.");
                        }
                        layer = new LayerImageConfiguration();
                        LayerImageConfiguration imageLayer = (LayerImageConfiguration)layer;
                        imageLayer.setPath(path);
                    } else if (layerChildElement.getTagName().equals("shape")) {
                        // <shape shape-type="round-rect" radius="5" />
                        String shapeType = layerChildElement.getAttribute("shape-type");
                        if ((shapeType == null) || (shapeType.length() == 0)) {
                            throw new SystemException("'shape' tag is missing 'shape-type' attribute");
                        }
                        layer = new LayerShapeConfiguration();
                        LayerShapeConfiguration shapeLayer = (LayerShapeConfiguration)layer;
                        String radius = layerChildElement.getAttribute("radius");
                        if (shapeType.equals("round-rect")) {
                            shapeLayer.setShapeType(LayerShapeConfiguration.SHAPE_TYPE_ROUND_RECTANGLE);
                    	} else if (shapeType.equals("rect")) {
                            shapeLayer.setShapeType(LayerShapeConfiguration.SHAPE_TYPE_RECTANGLE);
                    	} else if (shapeType.equals("ellipse")) {
                            shapeLayer.setShapeType(LayerShapeConfiguration.SHAPE_TYPE_ELLIPSE);
                        } else {
                            throw new SystemException("Error, 'shape' does not have a valid 'shape-type', type = " + shapeType);
                        }
                        if ((radius != null) && (radius.length() > 0)) {
                            shapeLayer.setRadius(new Integer(radius));
                        }
                        
                        String penColor = layerChildElement.getAttribute("pen-color");
                        String penSize = layerChildElement.getAttribute("pen-size");
                        String brushColor = layerChildElement.getAttribute("brush-color");
                        if ((penColor != null) && (penColor.length() > 0)) {
                            shapeLayer.setPenColor(penColor);
                        }
                        if ((penSize != null) && (penSize.length() > 0)) {
                            shapeLayer.setPenSize(new Integer(penSize));
                        }
                        if ((brushColor != null) && (brushColor.length() > 0)) {
                            shapeLayer.setBrushColor(brushColor);
                        }
                    }
                }
            }
            if (layer == null) {
                layer = new LayerConfiguration();
            }
            
            String index = layerElement.getAttribute("index");
            String left = layerElement.getAttribute("left");
            String top = layerElement.getAttribute("top");
            String width = layerElement.getAttribute("width");
            String height = layerElement.getAttribute("height");
            if ((width != null) && (width.length() > 0)) {
                layer.setWidth(new Integer(width));
            }
            if ((height != null) && (height.length() > 0)) {
                layer.setHeight(new Integer(height));
            }
            
            String antiAlias = layerElement.getAttribute("anti-alias");
            if ((antiAlias != null) && (antiAlias.startsWith("fa"))) {
                layer.setAntiAliasing(false);
            } else {
                layer.setAntiAliasing(true);
            }
            if ((left != null) && (left.length() > 0)) {
                try {
                    layer.setLeft(new Integer(left));
                } catch (Exception ex) {
                    throw new SystemException("Exception parsing 'left' of layer: " + name);
                }
            }
            if ((top != null) && (top.length() > 0)) {
                try {
	                layer.setTop(new Integer(top));
	            } catch (Exception ex) {
	                throw new SystemException("Exception parsing 'top' of layer: " + name);
	            }
            }
            
            layer.setName(name);
            if ((index != null) && (index.trim().length() > 0)) {
                try {
                    layer.setIndex(new Integer(index));
                } catch (Exception ex) {
                    throw new SystemException("Illegal value for layer index attribute: " + index);
                }
            }
            imageConfig.addLayer(layer);
            
        }
    }
    
    
    
    
    /**
     * @return Returns the imageConfigMap.
     */
    public HashMap getImageConfigMap() {
        return imageConfigMap;
    }

}
